package ch.poole.openinghoursfragment.pickers;

import ch.poole.openinghoursfragment.ResourceTable;
import ch.poole.openinghoursfragment.pickers.dialogpicker.DialogPickerView;
import ch.poole.openinghoursfragment.pickers.dialogpicker.NumberPickerView;
import com.lxj.xpopup.impl.ConfirmPopupView;
import com.lxj.xpopup.interfaces.OnConfirmListener;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Picker;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;

import static ohos.agp.components.Component.HIDE;
import static ohos.agp.components.Component.VISIBLE;

/**
 * Display a dialog allowing the user to select values for a start date and optionally an end date
 */
public class TimeRangePicker {
    public static final int NOTHING_SELECTED = Integer.MIN_VALUE;

    private static final String TITLE = "title";
    private static final String START_HOUR = "startHour";
    private static final String START_MINUTE = "startMinute";
    private static final String START_ONLY = "startOnly";
    private static final String END_HOUR = "endHour";
    private static final String END_MINUTE = "endMinute";
    private static final String INCREMENT = "increment";

    private static final String TAG = "fragment_timepicker";
    private static SetTimeRangeListener listener;

    private static final int MAX_MINUTES = 59;
    private static final int MAX_EXTENDED_HOURS = 48;
    private static String[] hourValues;
    private static String[] minValues;
    private static ConfirmPopupView popupView;
    private static NumberPickerView npvStartHour;
    private static NumberPickerView npvStartMinute;
    private static NumberPickerView npvEndHour;
    private static NumberPickerView npvEndMinute;

    /**
     * Show the TimeRangePicker dialog
     *
     * @NonNull Fragment parentFragment, int title, int startHour, int startMinute, int endHour, int endMinute, int increment
     */
    /**
     * Show the TimeRangePicker dialog
     *
     * @param context       context
     * @param title         title
     * @param startHour     startHour
     * @param startMinute   startMinute
     * @param endHour       endHour
     * @param endMinute     endMinute
     * @param increment     increment
     * @param rangeListener rangeListener
     * @throws IOException
     */
    public static void showDialog(Context context, int title, int startHour, int startMinute, int endHour, int endMinute, int increment, SetTimeRangeListener rangeListener) {
        try {
            final String titleStr = context.getResourceManager().getElement(title).getString();
            newInstance(context, titleStr, startHour, startMinute, false, endHour, endMinute, increment, rangeListener);
            if (popupView != null) {
                popupView.show();
            }
        } catch (IOException | NotExistException | WrongTypeException e) {
            e.printStackTrace();
        }
    }


    /**
     * Show the TimeRangePicker dialog
     *
     * @param context       context
     * @param title         title
     * @param startHour     startHour
     * @param startMinute   startMinute
     * @param increment     increment
     * @param rangeListener rangeListener
     * @throws IOException
     */
    public static void showDialog(Context context, int title, int startHour, int startMinute, int increment, SetTimeRangeListener rangeListener) {
        try {
            final String titleStr = context.getResourceManager().getElement(title).getString();
            newInstance(context, titleStr, startHour, startMinute, true, 0, 0, increment, rangeListener);
            if (popupView != null) {
                popupView.show();
            }
        } catch (IOException | NotExistException | WrongTypeException e) {
            e.printStackTrace();
        }
    }

    /**
     * Create a new instance of DateRangePicker
     *
     * @param context       context
     * @param title         resource id for the title to display
     * @param startHour     initial start hour
     * @param startMinute   initial start minute
     * @param startOnly     only show a picker for one time
     * @param endHour       initial end hour
     * @param endMinute     initial end minute
     * @param increment     minute tick size
     * @param rangeListener rangeListener
     * @return an instance of TimeRangePicker
     */
    private static TimeRangePicker newInstance(Context context, String title, int startHour, int startMinute, boolean startOnly, int endHour, int endMinute, int increment, SetTimeRangeListener rangeListener) {
        TimeRangePicker f = new TimeRangePicker();
        listener = rangeListener;
        hourValues = new String[MAX_EXTENDED_HOURS + 1];
        for (int i = 0; i <= MAX_EXTENDED_HOURS; i++) {
            hourValues[i] = String.format("%02d", i);
        }

        int ticks = 60 / increment;
        minValues = new String[ticks];
        for (int i = 0; i < ticks; i++) {
            minValues[i] = String.format("%02d", i * increment);
        }

        popupView = DialogPickerView.getInstance(context, title, "OK", ResourceTable.Layout_dialog_time_range_picker, new OnConfirmListener() {

            @Override
            public void onConfirm() {
                int startHourValue = npvStartHour.getValue();
                int startMinuteValue = npvStartMinute.getValue() * increment;
                int endHourValue = npvEndHour.getValue();
                int endMinuteValue = npvEndMinute.getValue() * increment;

                listener.setTimeRange(startHourValue, startMinuteValue, endHourValue, endMinuteValue);
            }
        }, null).build();
        initDialogView(startHour, startMinute, startOnly, endHour, endMinute, increment);

        return f;
    }

    private static void initDialogView(int startHour, int startMinute, boolean startOnly, int endHour, int endMinute, int increment) {
        if (popupView != null) {
            npvStartHour = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_startHour);
            npvStartHour.setDisplayedData(hourValues);
            npvStartHour.setMinValue(0);
            npvStartHour.setMaxValue(23);
            if (startHour < 0) {
                startHour = 0;
            }
            npvStartHour.setValue(startHour);

            npvStartMinute = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_startMinute);

            int maxMinutes = MAX_MINUTES / increment;
            npvStartMinute.setDisplayedData(minValues);
            npvStartMinute.setMinValue(0);
            npvStartMinute.setMaxValue(maxMinutes);
            if (startMinute < 0) {
                startMinute = 0;
            }
            npvStartMinute.setValue(startMinute / increment);

            npvEndHour = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_endHour);
            npvEndMinute = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_endMinute);
            DirectionalLayout endView = (DirectionalLayout) popupView.findComponentById(ResourceTable.Id_endView);
            if (startOnly) {
                endView.setVisibility(HIDE);
            } else {
                int finalEndMinute = endMinute;
                npvEndHour.setScrollListener(new Picker.ScrolledListener() {
                    int em = finalEndMinute;

                    @Override
                    public void onScrollStateUpdated(Picker picker, int i) {
                        if (picker.getValue() == 48) {
                            npvEndMinute.setDisplayedData(new String[]{"00"});
                            npvEndMinute.setMinValue(0);
                            npvEndMinute.setMaxValue(0);
                            npvEndMinute.setValue(0);
                        } else {
                            npvEndMinute.setDisplayedData(minValues);
                            npvEndMinute.setMinValue(0);
                            npvEndMinute.setMaxValue(maxMinutes);
                            if (em < 0) {
                                em = 0;
                            }
                            npvEndMinute.setValue(em / increment);
                        }
                    }
                });
                endView.setVisibility(VISIBLE);
                npvEndHour.setDisplayedData(hourValues);
                npvEndHour.setMinValue(0);
                npvEndHour.setMaxValue(MAX_EXTENDED_HOURS);
                npvEndHour.setValue(endHour);

                npvEndMinute.setDisplayedData(minValues);
                npvEndMinute.setMinValue(0);
                npvEndMinute.setMaxValue(maxMinutes);
                if (endMinute < 0) {
                    endMinute = 0;
                }
                npvEndMinute.setValue(endMinute / increment);

                if (npvEndHour.getValue() == 48) {
                    npvEndMinute.setDisplayedData(new String[]{"00"});
                    npvEndMinute.setMinValue(0);
                    npvEndMinute.setMaxValue(0);
                    npvEndMinute.setValue(0);
                } else {
                    npvEndMinute.setDisplayedData(minValues);
                    npvEndMinute.setMinValue(0);
                    npvEndMinute.setMaxValue(maxMinutes);
                    if (endMinute < 0) {
                        endMinute = 0;
                    }
                    npvEndMinute.setValue(endMinute / increment);
                }
            }

        }
    }
}
